package pdf;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.interactive.action.PDAction;
import org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDDestination;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDNamedDestination;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageDestination;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

public class SplitPdfUtil {

    public static void main(String[] args) throws IOException {
    }

    /**
     * 根据书签来分割pdf，注意书签只会读取第一层，所以书签要完成，一个书签一个文件
     *
     * @param filePath 文件路径
     * @throws IOException 文件读写异常
     */
    public static void splitPdfByBook(String filePath) throws IOException {
        File file = new File(filePath);
        PDDocument document = PDDocument.load(file);
        System.out.println("getNumberOfPages:" + document.getNumberOfPages());
        //getDocumentOutline方法的主要作用是获取PDF文档的书签（Bookmarks）根节点
        PDDocumentOutline outline = document.getDocumentCatalog().getDocumentOutline();
        Iterable<PDOutlineItem> children = outline.children();
        Iterator<PDOutlineItem> iterator = children.iterator();
        List<Map<String, Integer>> mapList = new ArrayList<>();
        while (iterator.hasNext()) {
            PDOutlineItem current = iterator.next();
            String title = current.getTitle();
//            System.out.println(title);
            PDDestination destination = current.getDestination();
            if (destination instanceof PDPageDestination) {
                // 如果是页面目的地，直接获取页码
                int pageNumber = ((PDPageDestination) destination).retrievePageNumber() + 1;
                System.out.println("PDPageDestination:" + title + "|" + pageNumber);
                Map<String, Integer> pageMap = new LinkedHashMap<>();
                pageMap.put(title, pageNumber);
                mapList.add(pageMap);
            }
            else if (destination instanceof PDNamedDestination) {
                // 如果是命名目的地，通过文档目录查找页码
                PDPageDestination pageDestination = document.getDocumentCatalog().findNamedDestinationPage((PDNamedDestination) destination);
                int pageNumber = pageDestination != null ? pageDestination.retrievePageNumber() + 1 : -1; // 页码从1开始计数，如果找不到则返回-1
                System.out.println("PDNamedDestination:" + title + "|" + pageNumber);
                Map<String, Integer> pageMap = new LinkedHashMap<>();
                pageMap.put(title, pageNumber);
                mapList.add(pageMap);
            }
            else {
                // 处理其他类型的目标位置（如动作等）
                PDAction action = current.getAction();
                if (action instanceof PDActionGoTo) {
                    PDActionGoTo goTo = (PDActionGoTo) action;
                    destination = goTo.getDestination();
                    if (destination instanceof PDNamedDestination) {
                        // 如果是命名目的地，通过文档目录查找页码
                        PDPageDestination pageDestination = document.getDocumentCatalog().findNamedDestinationPage((PDNamedDestination) destination);
                        int pageNumber = pageDestination != null ? pageDestination.retrievePageNumber() + 1 : -1; // 页码从1开始计数，如果找不到则返回-1
                        System.out.println("PDNamedDestination:" + title + "|" + pageNumber);
                        Map<String, Integer> pageMap = new LinkedHashMap<>();
                        pageMap.put(title, pageNumber);
                        mapList.add(pageMap);
                    }
                    else {
                        System.out.println("Nastother:" + destination.getClass());
                    }
                }
                else {
                    System.out.println("other:" + action.getClass());
                }
            }
        }
        System.out.println(mapList);
        for (Map<String, Integer> next : mapList) {
            int currentIndex = mapList.indexOf(next);
            Map.Entry<String, Integer> entry = next.entrySet().iterator().next();
            String fileName = entry.getKey();
            int start = entry.getValue();
            System.out.println(next);
            int end;
            if (currentIndex < mapList.size() - 1) {
                Map<String, Integer> nextMap = mapList.get(currentIndex + 1);
                System.out.println("nextFile:" + nextMap.keySet().stream().findFirst().get());
                end = nextMap.values().stream().findFirst().get() - 1;
            }
            else {
                end = document.getNumberOfPages() - 1;
            }
            System.out.println(currentIndex + ":" + fileName + "|start:" + start + ",end:" + end);
            PDDocument saveDocument = new PDDocument();
            for (int i = start; i <= end; i++) {
                saveDocument.addPage(document.getPage(i));
            }
            File splitFile = new File("G:\\书籍\\database\\data_concepts\\" + File.separator + currentIndex + "_" + fileName + ".pdf");
            System.out.println(splitFile.getAbsolutePath());
            saveDocument.save(splitFile);
            saveDocument.close();
        }
    }
}

